use tauri::State;
use serde::{Deserialize, Serialize};
use tracing::{info, error, debug};
use uuid::Uuid;
use chrono;

use crate::database::DatabaseManager;
use crate::database::schema::Device;
use crate::error::{AppError, Result as AppResult};

#[derive(Debug, Serialize, Deserialize)]
pub struct DeviceResponse {
    pub id: String,
    pub name: String,
    pub device_type: String,
    pub platform: String,
    pub status: String,
    pub model: Option<String>,
    pub resolution: Option<String>,
    pub version: Option<String>,
    pub last_active: Option<String>,
    pub created_at: String,
    pub updated_at: String,
}

impl From<Device> for DeviceResponse {
    fn from(device: Device) -> Self {
        Self {
            id: device.id,
            name: device.name,
            device_type: device.device_type,
            platform: device.platform,
            status: device.status,
            model: device.device_info.as_ref()
                .and_then(|info| serde_json::from_str::<serde_json::Value>(info).ok())
                .and_then(|info| info.get("model").and_then(|v| v.as_str().map(|s| s.to_string()))),
            resolution: device.device_info.as_ref()
                .and_then(|info| serde_json::from_str::<serde_json::Value>(info).ok())
                .and_then(|info| info.get("screen_resolution").and_then(|v| v.as_str().map(|s| s.to_string()))),
            version: device.device_info.as_ref()
                .and_then(|info| serde_json::from_str::<serde_json::Value>(info).ok())
                .and_then(|info| info.get("os_version").and_then(|v| v.as_str().map(|s| s.to_string()))),
            last_active: device.last_heartbeat.map(|dt| dt.format("%Y-%m-%d %H:%M:%S").to_string()),
            created_at: device.created_at.format("%Y-%m-%d %H:%M:%S").to_string(),
            updated_at: device.updated_at.format("%Y-%m-%d %H:%M:%S").to_string(),
        }
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CreateDeviceRequest {
    pub name: String,
    pub device_type: String,
    pub platform: String,
    pub connection_config: serde_json::Value,
}

/// 获取设备列表
#[tauri::command]
pub async fn get_devices(
    db: State<'_, DatabaseManager>
) -> Result<Vec<DeviceResponse>, String> {
    info!("Fetching devices list");
    
    match db.get_devices().await {
        Ok(devices) => {
            let device_responses: Vec<DeviceResponse> = devices
                .into_iter()
                .map(DeviceResponse::from)
                .collect();
            
            debug!("Retrieved {} devices", device_responses.len());
            Ok(device_responses)
        }
        Err(e) => {
            error!("Failed to fetch devices: {}", e);
            Err(format!("Failed to fetch devices: {}", e))
        }
    }
}

/// 根据ID获取设备
#[tauri::command]
pub async fn get_device(
    id: String,
    db: State<'_, DatabaseManager>
) -> Result<Option<DeviceResponse>, String> {
    info!("Fetching device: {}", id);
    
    match db.get_device_by_id(&id).await {
        Ok(Some(device)) => Ok(Some(DeviceResponse::from(device))),
        Ok(None) => Ok(None),
        Err(e) => {
            error!("Failed to fetch device {}: {}", id, e);
            Err(format!("Failed to fetch device: {}", e))
        }
    }
}

/// 创建新设备
#[tauri::command]
pub async fn create_device(
    request: CreateDeviceRequest,
    db: State<'_, DatabaseManager>
) -> Result<String, String> {
    info!("Creating device: {}", request.name);
    
    let device = Device {
        id: uuid::Uuid::new_v4().to_string(),
        name: request.name,
        device_type: request.device_type,
        platform: request.platform,
        status: "offline".to_string(),
        connection_config: Some(serde_json::to_string(&request.connection_config).unwrap()),
        device_info: None,
        performance_config: None,
        proxy_config: None,
        last_heartbeat: None,
        last_error: None,
        uptime_seconds: Some(0),
        total_tasks_completed: 0,
        total_errors: 0,
        created_at: chrono::Utc::now().naive_utc(),
        updated_at: chrono::Utc::now().naive_utc(),
    };
    
    let device_id = device.id.clone();
    match db.create_device(&device).await {
        Ok(_) => {
            info!("Device created successfully: {}", device_id);
            Ok(device_id)
        }
        Err(e) => {
            error!("Failed to create device: {}", e);
            Err(format!("Failed to create device: {}", e))
        }
    }
}

/// 更新设备状态
#[tauri::command]
pub async fn update_device_status(
    id: String,
    status: String,
    db: State<'_, DatabaseManager>
) -> Result<(), String> {
    info!("Updating device {} status to {}", id, status);
    
    match db.update_device_status(&id, &status).await {
        Ok(_) => {
            info!("Device status updated successfully");
            Ok(())
        }
        Err(e) => {
            error!("Failed to update device status: {}", e);
            Err(format!("Failed to update device status: {}", e))
        }
    }
}

/// 连接设备
#[tauri::command]
pub async fn connect_device(
    id: String,
    db: State<'_, DatabaseManager>
) -> Result<(), String> {
    info!("Connecting device: {}", id);
    
    // TODO: 实现实际的设备连接逻辑
    // 这里应该包括 ADB 连接、WebDriverAgent 连接等
    
    match db.update_device_status(&id, "connecting").await {
        Ok(_) => {
            // 模拟连接过程
            tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
            
            // 更新为在线状态
            match db.update_device_status(&id, "online").await {
                Ok(_) => {
                    info!("Device connected successfully: {}", id);
                    Ok(())
                }
                Err(e) => {
                    error!("Failed to update device status after connection: {}", e);
                    Err(format!("Connection failed: {}", e))
                }
            }
        }
        Err(e) => {
            error!("Failed to initiate device connection: {}", e);
            Err(format!("Failed to connect device: {}", e))
        }
    }
}

/// 断开设备连接
#[tauri::command]
pub async fn disconnect_device(
    id: String,
    db: State<'_, DatabaseManager>
) -> Result<(), String> {
    info!("Disconnecting device: {}", id);
    
    match db.update_device_status(&id, "offline").await {
        Ok(_) => {
            info!("Device disconnected successfully: {}", id);
            Ok(())
        }
        Err(e) => {
            error!("Failed to disconnect device: {}", e);
            Err(format!("Failed to disconnect device: {}", e))
        }
    }
}

/// 删除设备
#[tauri::command]
pub async fn delete_device(
    id: String,
    db: State<'_, DatabaseManager>
) -> Result<(), String> {
    info!("Deleting device: {}", id);
    
    match db.delete_device(&id).await {
        Ok(_) => {
            info!("Device deleted successfully: {}", id);
            Ok(())
        }
        Err(e) => {
            error!("Failed to delete device: {}", e);
            Err(format!("Failed to delete device: {}", e))
        }
    }
}

/// 更新设备心跳
#[tauri::command]
pub async fn update_device_heartbeat(
    id: String,
    db: State<'_, DatabaseManager>
) -> Result<(), String> {
    debug!("Updating heartbeat for device: {}", id);
    
    match db.update_device_heartbeat(&id).await {
        Ok(_) => Ok(()),
        Err(e) => {
            error!("Failed to update device heartbeat: {}", e);
            Err(format!("Failed to update heartbeat: {}", e))
        }
    }
}

/// 获取设备统计信息
#[tauri::command]
pub async fn get_device_stats(
    db: State<'_, DatabaseManager>
) -> Result<serde_json::Value, String> {
    debug!("Fetching device statistics");
    
    match db.get_device_stats().await {
        Ok(stats) => Ok(stats),
        Err(e) => {
            error!("Failed to fetch device stats: {}", e);
            Err(format!("Failed to fetch device stats: {}", e))
        }
    }
}